<template>
    <div class="face-compare-page">
        <div class="title">人脸比对</div>

        <div class="input-group">
            <input v-model="phone" placeholder="请输入用户名" class="input-field" />
            <button @click="captureAndCompare" class="compare-btn">比对</button>
        </div>

        <!-- 显示视频流 -->
        <div class="video-container">
            <video ref="video" autoplay class="video-element"></video>
        </div>

        <!-- 显示画布 -->
        <canvas ref="canvas" class="canvas-element"></canvas>

        <!-- 比对结果展示 -->
        <div v-if="compareResult" class="result-container">
            <h3 class="result-title">比对结果</h3>
            <p class="result-message"
                :class="{ success: compareResult.code === 200, error: compareResult.code !== 200 }">
                {{ compareResult.msg }}
            </p>
            <div v-if="compareResult.data" class="result-data">
                <p><strong>相似度：</strong>{{ compareResult.data.similarity }}%</p>
                <p><strong>比对详情：</strong>{{ compareResult.data.details }}</p>
            </div>
        </div>
    </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount } from 'vue';
import http from '../http';

// 存储用户名
const phone = ref('');
// 视频元素引用
const video = ref<HTMLVideoElement | null>(null);
// 画布元素引用
const canvas = ref<HTMLCanvasElement | null>(null);
// 从本地存储中获取的 OSS 图片 URL
const ossImageUrl = ref<string>('');
// 比对结果
const compareResult = ref<{ code: number; msg: string; data?: { similarity: number; details: string } } | null>(null);

// 当组件挂载时，初始化摄像头获取视频流并从本地存储中获取图片 URL
onMounted(() => {
    initCamera();
    fetchOssImageFromLocalStorage(); // 获取 OSS 图片 URL
});

// 当组件卸载前，关闭摄像头视频流
onBeforeUnmount(() => {
    stopCamera();
});

// 初始化摄像头，获取视频流
const initCamera = async () => {
    try {
        const stream = await navigator.mediaDevices.getUserMedia({ video: true });
        video.value!.srcObject = stream;
        video.value!.play();
    } catch (error) {
        console.error('初始化摄像头出错：', error);
    }
};

// 停止摄像头视频流
const stopCamera = () => {
    if (video.value && video.value.srcObject) {
        const tracks = (video.value.srcObject as MediaStream).getTracks();
        tracks.forEach((track) => track.stop());
    }
};

// 从本地存储中获取 OSS 图片 URL
const fetchOssImageFromLocalStorage = () => {
    const storedUrl = localStorage.getItem('file_url'); // 假设存储的键为 "ossImageUrl"
    if (storedUrl) {
        ossImageUrl.value = storedUrl;
        console.log('从本地存储获取到的 OSS 图片 URL:', ossImageUrl.value);
    } else {
        alert('未找到本地存储中的 OSS 图片 URL');
    }
};

// 捕获人脸图像并进行比对操作
const captureAndCompare = async () => {
    try {
        if (!ossImageUrl.value) {
            alert('OSS 图片 URL 不存在，请检查本地存储');
            return;
        }

        // 等待视频流稳定，可根据实际情况调整等待时间
        await new Promise((resolve) => setTimeout(resolve, 1000));

        canvas.value!.width = video.value!.videoWidth;
        canvas.value!.height = video.value!.videoHeight;
        const ctx = canvas.value!.getContext('2d');
        if (ctx) {
            ctx.drawImage(video.value!, 0, 0, canvas.value!.width, canvas.value!.height);
            // 将画布内容转换为 Base64 编码的图片
            const videoImageData = canvas.value!.toDataURL('image/jpeg');
            const videoBase64 = videoImageData.split(',')[1];
            // 显示在画布上
            canvas.value!.style.display = 'block';
            // 构造表单数据
            const formData = new FormData();
            formData.append('img1_url', ossImageUrl.value); // 从本地存储获取的 OSS 图片 URL
            formData.append('img2', videoBase64); // 视频截图 Base64 数据

            // 调用后端接口上传图片并进行比对
            const response = await http.post('app/face/', formData);
            console.log('人脸比对结果：', response.data);
            compareResult.value = response.data;
        }
    } catch (error) {
        console.error('人脸比对出错：', error);
    } finally {
        stopCamera();
    }
};
</script>

<style scoped>
.face-compare-page {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    width: 400px;
    margin: 0 auto;
    padding: 20px;
    background-color: #f7f8fa;
    border-radius: 10px;
    box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
}

.title {
    font-size: 24px;
    font-weight: bold;
    color: #333;
    margin-bottom: 20px;
}

.input-group {
    display: flex;
    width: 100%;
    margin-bottom: 20px;
}

.input-field {
    flex: 1;
    padding: 10px;
    font-size: 16px;
    border: 1px solid #ccc;
    border-radius: 5px 0 0 5px;
    outline: none;
    box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
}

.compare-btn {
    padding: 10px 20px;
    font-size: 16px;
    font-weight: bold;
    color: #fff;
    background: linear-gradient(45deg, #4caf50, #66bb6a);
    border: none;
    border-radius: 0 5px 5px 0;
    cursor: pointer;
}

.compare-btn:hover {
    background: linear-gradient(45deg, #43a047, #5ebd63);
}

.video-container {
    width: 100%;
    margin-bottom: 20px;
    border-radius: 10px;
    overflow: hidden;
    box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
}

.video-element {
    width: 100%;
    height: auto;
    border-radius: 10px;
}

.canvas-element {
    width: 100%;
    height: auto;
    border: 1px solid #ccc;
    border-radius: 10px;
    box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
    margin-bottom: 20px;
}

.result-container {
    width: 100%;
    padding: 15px;
    background-color: #fff;
    border-radius: 10px;
    box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
    text-align: left;
}

.result-title {
    font-size: 18px;
    font-weight: bold;
    color: #333;
    margin-bottom: 10px;
}

.result-message {
    font-size: 16px;
    margin-bottom: 10px;
}

.result-message.success {
    color: #4caf50;
}

.result-message.error {
    color: red;
}

.result-data p {
    font-size: 16px;
    margin: 5px 0;
}
</style>
